# -*- coding: utf-8 -*-
"""
数据服务模块 - API视图定义

本文件定义了测试DEMO中数据服务相关的所有API视图，包括：

1. 数据源管理API
   - DataSourceListView: 获取活跃数据源列表
   - 支持数据源的查询和管理

2. 数据同步管理API
   - DataSyncTaskListView: 获取数据同步任务列表
   - DataSyncLogListView: 获取数据同步日志列表
   - create_sync_task: 创建新的数据同步任务
   - sync_status: 获取数据同步状态
   - 支持任务的创建、监控和日志查询

3. 基金数据查询API
   - FundDataListView: 获取基金数据列表（支持搜索和过滤）
   - FundDataDetailView: 获取基金详细信息
   - fund_search: 基金搜索接口（支持模糊搜索）
   - fund_statistics: 获取基金统计信息
   - fund_performance: 获取基金业绩表现
   - export_fund_data: 导出基金数据

4. 基金净值查询API
   - FundNetValueListView: 获取指定基金的净值列表
   - FundNetValueSearchView: 基金净值搜索（支持日期范围）
   - 支持净值的时间序列查询和分析

5. 市场数据查询API
   - MarketDataListView: 获取市场数据列表
   - market_indicators: 获取市场指标数据
   - 支持各种市场指标的查询和分析

6. 数据下载和导入API
   - download_fund_list: 下载基金列表数据
   - download_fund_basic_info: 下载基金基本信息
   - download_open_fund_info: 下载开放式基金信息
   - 集成AKShare数据源，支持实时数据获取

所有API都要求用户认证，支持分页、搜索、过滤等功能。
视图采用Django REST Framework实现，提供标准的RESTful接口。
集成了完整的错误处理和日志记录机制。

Author: zhaozeliang
Date: 2025-09-06
"""

from rest_framework import generics, status, permissions
from rest_framework.decorators import api_view, permission_classes, action
from rest_framework.response import Response
from django.shortcuts import get_object_or_404
from django.db.models import Q, Avg, Max, Min, Exists, OuterRef
from django.utils import timezone
from django.http import JsonResponse, HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
from datetime import datetime, timedelta
import pandas as pd
import io
import logging
from .models import DataSource, DataSyncTask, DataSyncLog, FundInfo, FundInfoDetail, FundNavDetail, MarketData, FinalFundScraper
from .serializers import (
    DataSourceSerializer, DataSyncTaskSerializer, DataSyncLogSerializer,
    FundInfoSerializer, FundInfoDetailSerializer, FundInfoDetailTableSerializer, FundNavDetailSerializer,
    MarketDataSerializer, DataSyncCreateSerializer, FundSearchSerializer,
    FinalFundScraperSerializer
)
from .akshare_service import akshare_service
from .fund_data_downloader import FundDataDownloader

# 导入基金净值爬虫
import sys
sys.path.append('/Users/alan/Library/CloudStorage/SynologyDrive-Mac/财务解决方案/wealth_management_system/backend')
from fund_nav_scraper import FundNavScraper, DownloadStatus, FundNavAPI
from config import get_database_config

logger = logging.getLogger(__name__)


class DataSourceListView(generics.ListAPIView):
    """数据源列表视图"""
    queryset = DataSource.objects.filter(is_active=True)
    serializer_class = DataSourceSerializer
    permission_classes = [permissions.IsAuthenticated]


class DataSyncTaskListView(generics.ListAPIView):
    """数据同步任务列表视图"""
    queryset = DataSyncTask.objects.all().order_by('-created_at')
    serializer_class = DataSyncTaskSerializer
    permission_classes = [permissions.IsAuthenticated]


class DataSyncLogListView(generics.ListAPIView):
    """数据同步日志列表视图"""
    serializer_class = DataSyncLogSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_queryset(self):
        queryset = DataSyncLog.objects.all().order_by('-created_at')
        task_id = self.request.query_params.get('task_id')
        if task_id:
            queryset = queryset.filter(task_id=task_id)
        return queryset


class FundDataListView(generics.ListAPIView):
    """基金数据列表视图"""
    serializer_class = FundInfoDetailTableSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_paginated_response(self, data):
        # 如果请求参数包含all=true或page_size>=1000，则不分页
        if (self.request.query_params.get('all') == 'true' or 
            int(self.request.query_params.get('page_size', 0)) >= 1000):
            return Response({
                'results': data,
                'total_count': len(data)
            })
        return super().get_paginated_response(data)
    
    def paginate_queryset(self, queryset):
        # 如果请求参数包含all=true或page_size>=1000，则不分页
        if (self.request.query_params.get('all') == 'true' or 
            int(self.request.query_params.get('page_size', 0)) >= 1000):
            return None
        
        # 允许更大的page_size，最大1000
        page_size = min(int(self.request.query_params.get('page_size', 20)), 1000)
        if hasattr(self, 'paginator'):
            self.paginator.page_size = page_size
        return super().paginate_queryset(queryset)
    
    def get_queryset(self):
        queryset = FundInfoDetail.objects.all().order_by('fund_code')
        
        # 搜索过滤
        search = self.request.query_params.get('search')
        if search:
            queryset = queryset.filter(
                Q(fund_name__icontains=search) |
                Q(fund_code__icontains=search) |
                Q(fund_company__icontains=search)
            )
        
        # 基金类型过滤
        fund_type = self.request.query_params.get('fund_type')
        if fund_type:
            queryset = queryset.filter(fund_type=fund_type)
        
        return queryset


class FundDataDetailView(generics.RetrieveAPIView):
    """基金数据详情视图"""
    queryset = FundInfo.objects.all()
    serializer_class = FundInfoDetailSerializer
    permission_classes = [permissions.IsAuthenticated]
    lookup_field = 'fund_code'


class FundNetValueListView(generics.ListAPIView):
    """基金净值列表视图"""
    serializer_class = FundNavDetailSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_queryset(self):
        fund_code = self.kwargs['fund_code']
        queryset = FundNavDetail.objects.filter(fund_code=fund_code).order_by('-nav_date')
        
        # 日期范围过滤
        start_date = self.request.query_params.get('start_date')
        end_date = self.request.query_params.get('end_date')
        
        if start_date:
            try:
                start_date = datetime.strptime(start_date, '%Y-%m-%d').date()
                queryset = queryset.filter(nav_date__gte=start_date)
            except ValueError:
                pass
        
        if end_date:
            try:
                end_date = datetime.strptime(end_date, '%Y-%m-%d').date()
                queryset = queryset.filter(nav_date__lte=end_date)
            except ValueError:
                pass
        
        return queryset


class FundNetValueSearchView(generics.ListAPIView):
    """基金净值搜索视图"""
    serializer_class = FundNavDetailSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_paginated_response(self, data):
        # 如果请求参数包含all=true或page_size>=1000，则不分页
        if (self.request.query_params.get('all') == 'true' or 
            int(self.request.query_params.get('page_size', 0)) >= 1000):
            return Response(data)
        return super().get_paginated_response(data)
    
    def paginate_queryset(self, queryset):
        # 如果请求参数包含all=true或page_size>=1000，则不分页
        if (self.request.query_params.get('all') == 'true' or 
            int(self.request.query_params.get('page_size', 0)) >= 1000):
            return None
        return super().paginate_queryset(queryset)
    
    def get_queryset(self):
        queryset = FundNavDetail.objects.all().order_by('-nav_date')
        
        # 基金代码过滤
        fund_code = self.request.query_params.get('code')
        if fund_code:
            queryset = queryset.filter(fund_code__icontains=fund_code)
        
        # 基金名称过滤
        fund_name = self.request.query_params.get('name__icontains')
        if fund_name:
            queryset = queryset.filter(fund_code__in=FundInfo.objects.filter(
                fund_name__icontains=fund_name
            ).values_list('fund_code', flat=True))
        
        # 日期范围过滤
        price_date_gte = self.request.query_params.get('price_date__gte')
        price_date_lte = self.request.query_params.get('price_date__lte')
        
        if price_date_gte:
            try:
                start_date = datetime.strptime(price_date_gte, '%Y-%m-%d').date()
                queryset = queryset.filter(nav_date__gte=start_date)
            except ValueError:
                pass
        
        if price_date_lte:
            try:
                end_date = datetime.strptime(price_date_lte, '%Y-%m-%d').date()
                queryset = queryset.filter(nav_date__lte=end_date)
            except ValueError:
                pass
        
        return queryset


class MarketDataListView(generics.ListAPIView):
    """市场数据列表视图"""
    serializer_class = MarketDataSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_queryset(self):
        queryset = MarketData.objects.all().order_by('-data_date')
        
        # 指标类型过滤
        indicator_type = self.request.query_params.get('indicator_type')
        if indicator_type:
            queryset = queryset.filter(indicator_type=indicator_type)
        
        # 日期范围过滤
        days = self.request.query_params.get('days', 30)
        try:
            days = int(days)
            start_date = timezone.now().date() - timedelta(days=days)
            queryset = queryset.filter(data_date__gte=start_date)
        except ValueError:
            pass
        
        return queryset


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def create_sync_task(request):
    """创建数据同步任务"""
    serializer = DataSyncCreateSerializer(data=request.data)
    if serializer.is_valid():
        data_source_id = serializer.validated_data['data_source_id']
        sync_type = serializer.validated_data['sync_type']
        
        try:
            data_source = DataSource.objects.get(id=data_source_id)
            
            # 创建同步任务
            task = DataSyncTask.objects.create(
                name=f"{data_source.name}_{sync_type}_sync_{timezone.now().strftime('%Y%m%d_%H%M%S')}",
                data_source=data_source,
                sync_type=sync_type,
                status='pending'
            )
            
            # 设置同步参数
            sync_params = {}
            if sync_type == 'fund_data':
                fund_codes = request.data.get('fund_codes')
                if fund_codes:
                    sync_params['fund_codes'] = fund_codes
            elif sync_type == 'fund_net_value':
                fund_code = request.data.get('fund_code')
                days = request.data.get('days', 30)
                if not fund_code:
                    return Response({
                        'error': '同步净值数据需要指定基金代码'
                    }, status=status.HTTP_400_BAD_REQUEST)
                sync_params['fund_code'] = fund_code
                sync_params['days'] = days
            
            # 保存同步参数
            task.sync_params = sync_params
            task.save()
            
            # 启动同步任务
            try:
                from .sync_service import sync_service
                # 在后台执行同步（这里简化为同步执行，生产环境建议使用异步队列）
                import threading
                
                def run_sync():
                    sync_service.execute_sync_task(task.id)
                
                # 使用线程异步执行
                sync_thread = threading.Thread(target=run_sync)
                sync_thread.daemon = True
                sync_thread.start()
                
            except Exception as e:
                logger.error(f"启动同步任务失败: {str(e)}")
                task.status = 'failed'
                task.save()
            
            return Response({
                'task_id': task.id,
                'message': '数据同步任务已创建并启动',
                'status': task.status
            }, status=status.HTTP_201_CREATED)
            
        except DataSource.DoesNotExist:
            return Response({
                'error': '数据源不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"创建同步任务失败: {str(e)}")
            return Response({
                'error': '创建同步任务失败'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def fund_list_for_select(request):
    """
    获取基金列表用于下拉框选择
    返回基金代码和名称的简化列表
    """
    try:
        # 从fund_info_detail表获取基金列表
        funds = FundInfoDetail.objects.filter(
            fund_code__isnull=False,
            fund_name__isnull=False
        ).values('fund_code', 'fund_name').distinct().order_by('fund_code')
        
        fund_list = []
        for fund in funds:
            fund_list.append({
                'fund_code': fund['fund_code'],
                'fund_name': fund['fund_name'],
                'label': f"{fund['fund_code']} - {fund['fund_name']}"
            })
        
        return Response({
            'status': 'success',
            'data': fund_list,
            'count': len(fund_list)
        })
        
    except Exception as e:
        logger.error(f"获取基金列表失败: {e}")
        return Response({
            'status': 'error',
            'message': f'获取基金列表失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def fund_detail_info(request, fund_code):
    """
    获取指定基金的详细信息
    从fund_info_detail表获取完整的基金信息
    """
    try:
        fund_detail = FundInfoDetail.objects.filter(fund_code=fund_code).first()
        
        if not fund_detail:
            return Response({
                'status': 'error',
                'message': '未找到该基金的详细信息'
            }, status=status.HTTP_404_NOT_FOUND)
        
        # 序列化基金详细信息
        serializer = FundInfoDetailSerializer(fund_detail)
        
        return Response({
            'status': 'success',
            'data': serializer.data
        })
        
    except Exception as e:
        logger.error(f"获取基金详细信息失败: {e}")
        return Response({
            'status': 'error',
            'message': f'获取基金详细信息失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def fund_nav_history_chart(request, fund_code):
    """
    获取基金历史净值数据用于图表展示
    从fund_nav_detail_new表获取历史净值数据
    """
    try:
        # 获取查询参数
        days = request.GET.get('days')  # 如果不指定days，则获取所有历史数据
        
        # 构建查询条件
        queryset = FundNavDetail.objects.filter(fund_code=fund_code)
        
        # 如果指定了days参数，则限制日期范围
        if days:
            days = int(days)
            end_date = timezone.now().date()
            start_date = end_date - timedelta(days=days)
            queryset = queryset.filter(
                nav_date__gte=start_date,
                nav_date__lte=end_date
            )
        
        # 查询历史净值数据
        nav_data = queryset.order_by('nav_date').values(
            'nav_date', 'unit_nav', 'accumulated_nav', 'daily_growth_rate'
        )
        
        # 格式化数据用于图表
        chart_data = []
        for item in nav_data:
            chart_data.append({
                'date': item['nav_date'].strftime('%Y-%m-%d'),
                'unit_nav': float(item['unit_nav']) if item['unit_nav'] else None,
                'accumulated_nav': float(item['accumulated_nav']) if item['accumulated_nav'] else None,
                'daily_growth_rate': float(item['daily_growth_rate']) if item['daily_growth_rate'] else None
            })
        
        # 计算实际的日期范围
        if chart_data:
            actual_start_date = chart_data[0]['date']
            actual_end_date = chart_data[-1]['date']
        else:
            actual_start_date = None
            actual_end_date = None
        
        return Response({
            'status': 'success',
            'data': chart_data,
            'count': len(chart_data),
            'fund_code': fund_code,
            'date_range': {
                'start_date': actual_start_date,
                'end_date': actual_end_date
            }
        })
        
    except Exception as e:
        logger.error(f"获取基金历史净值数据失败: {e}")
        return Response({
            'status': 'error',
            'message': f'获取基金历史净值数据失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def stop_fund_download(request):
    """
    停止基金数据下载任务
    
    参数:
    - task_id: 任务ID（可选，用于验证）
    
    返回:
    - 停止结果
    """
    try:
        logger.info("请求停止基金数据下载任务")
        
        # 获取全局下载器实例
        downloader = get_fund_downloader()
        
        # 停止下载
        downloader.stop_download()
        
        # 获取当前状态
        progress_info = downloader.get_progress_info()
        
        logger.info("基金数据下载任务已停止")
        return Response({
            'status': 'success',
            'message': '基金数据下载任务已停止',
            'data': {
                'current_status': progress_info.get('status'),
                'progress': progress_info
            }
        })
        
    except Exception as e:
        logger.error(f"停止基金数据下载失败: {e}")
        return Response({
            'status': 'error',
            'message': f'停止下载失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def get_fund_download_status(request):
    """
    获取基金数据下载状态
    
    返回:
    - 当前下载状态和进度信息
    """
    try:
        # 获取全局下载器实例
        downloader = get_fund_downloader()
        
        # 获取状态和进度信息
        progress_info = downloader.get_progress_info()
        
        return Response({
            'status': 'success',
            'message': '获取下载状态成功',
            'data': {
                'task_id': id(downloader),
                'current_status': progress_info.get('status'),
                'progress': progress_info
            }
        })
        
    except Exception as e:
        logger.error(f"获取基金数据下载状态失败: {e}")
        return Response({
            'status': 'error',
            'message': f'获取状态失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def get_stored_fund_count(request):
    """
    获取已入库基金数量统计
    
    返回:
    - 基金列表总数
    - 已有详细信息的基金数量
    - 完成率等统计信息
    """
    try:
        # 统计基金列表总数
        total_funds = FundInfo.objects.count()
        
        # 统计已有详细信息的基金数量（fund_info_detail表中的记录）
        detailed_funds = FundInfoDetail.objects.count()
        
        # 计算完成率
        completion_rate = (detailed_funds / total_funds * 100) if total_funds > 0 else 0
        
        # 获取最后更新时间
        latest_detail_update = None
        if detailed_funds > 0:
            latest_detail = FundInfoDetail.objects.order_by('-updated_at').first()
            latest_detail_update = latest_detail.updated_at if latest_detail else None
        
        return Response({
            'status': 'success',
            'message': f'当前已入库基金详细信息数量: {detailed_funds}',
            'data': {
                'total_funds_in_info': total_funds,
                'total_funds_in_detail': detailed_funds,
                'completion_rate': round(completion_rate, 2),
                'remaining_count': total_funds - detailed_funds,
                'last_updated': latest_detail_update
            }
        })
        
    except Exception as e:
        logger.error(f"获取已入库基金统计失败: {e}")
        return Response({
            'status': 'error',
            'message': f'获取统计信息失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def continue_fund_detail_download(request):
    """
    继续下载基金详细信息
    从最新的基金代码开始，继续下载剩余的基金详细信息
    
    返回:
    - 任务启动状态
    - 剩余下载数量
    - 任务ID
    """
    try:
        logger.info("开始继续下载基金详细信息")
        
        # 获取全局下载器实例
        downloader = get_fund_downloader()
        
        # 检查当前状态
        progress_info = downloader.get_progress_info()
        current_status = progress_info.get('status')
        
        # 如果正在下载，返回当前状态
        if current_status == 'DOWNLOADING':
            return Response({
                'status': 'success',
                'message': '基金详细信息下载任务正在进行中',
                'data': {
                    'task_id': id(downloader),
                    'current_status': current_status,
                    'progress': progress_info
                }
            })
        
        # 计算需要继续下载的基金
        total_funds = FundInfo.objects.count()
        detailed_funds = FundInfoDetail.objects.count()
        remaining_count = total_funds - detailed_funds
        
        if remaining_count <= 0:
            return Response({
                'status': 'success',
                'message': '所有基金详细信息已下载完成',
                'data': {
                    'total_count': total_funds,
                    'completed_count': detailed_funds,
                    'remaining_count': 0,
                    'completion_rate': 100.0
                }
            })
        
        # 重置停止标志（如果之前被停止）
        if downloader.is_stopped():
            downloader.reset()
        
        # 启动继续下载任务（异步）
        import threading
        def continue_download_task():
            try:
                # 获取fund_info_detail表中最新的基金代码
                latest_detail = FundInfoDetail.objects.order_by('fund_code').last()
                
                if latest_detail:
                    # 从最新基金代码之后开始下载
                    start_code = latest_detail.fund_code
                    logger.info(f"从基金代码 {start_code} 之后开始继续下载")
                    
                    # 获取需要下载的基金列表（基金代码大于最新已下载的代码）
                    funds_to_download = FundInfo.objects.filter(
                        fund_code__gt=start_code
                    ).order_by('fund_code')
                else:
                    # 如果没有已下载的数据，从头开始
                    logger.info("没有已下载的基金详细信息，从头开始下载")
                    funds_to_download = FundInfo.objects.all().order_by('fund_code')
                
                # 执行下载
                downloader.download_fund_details_continue(funds_to_download)
                
            except Exception as e:
                logger.error(f"继续下载任务失败: {e}")
        
        # 在后台线程中启动下载
        download_thread = threading.Thread(target=continue_download_task, daemon=True)
        download_thread.start()
        
        # 返回任务启动成功的响应
        return Response({
            'status': 'success',
            'message': f'开始继续下载，剩余 {remaining_count} 只基金',
            'data': {
                'task_id': id(downloader),
                'total_count': total_funds,
                'completed_count': detailed_funds,
                'remaining_count': remaining_count,
                'current_status': 'DOWNLOADING',
                'progress': downloader.get_progress_info()
            }
        })
        
    except Exception as e:
        logger.error(f"启动继续下载失败: {e}")
        return Response({
            'status': 'error',
            'message': f'启动继续下载失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
    
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def fund_search(request):
    """基金搜索"""
    serializer = FundSearchSerializer(data=request.query_params)
    if serializer.is_valid():
        queryset = FundInfo.objects.all()
        
        # 关键词搜索
        keyword = serializer.validated_data.get('keyword')
        if keyword:
            queryset = queryset.filter(
                Q(fund_name__icontains=keyword) |
                Q(fund_code__icontains=keyword) |
                Q(fund_company__icontains=keyword)
            )
        
        # 基金类型过滤
        fund_type = serializer.validated_data.get('fund_type')
        if fund_type:
            queryset = queryset.filter(fund_type=fund_type)
        
        # 基金公司过滤
        fund_company = serializer.validated_data.get('fund_company')
        if fund_company:
            queryset = queryset.filter(fund_company__icontains=fund_company)
        
        # 风险等级过滤
        risk_level = serializer.validated_data.get('risk_level')
        if risk_level:
            queryset = queryset.filter(risk_level=risk_level)
        
        # 收益率范围过滤
        min_return = serializer.validated_data.get('min_return')
        max_return = serializer.validated_data.get('max_return')
        if min_return is not None:
            queryset = queryset.filter(annual_return__gte=min_return)
        if max_return is not None:
            queryset = queryset.filter(annual_return__lte=max_return)
        
        # 分页
        page_size = min(int(request.query_params.get('page_size', 20)), 100)
        page = int(request.query_params.get('page', 1))
        start = (page - 1) * page_size
        end = start + page_size
        
        total_count = queryset.count()
        funds = queryset[start:end]
        
        serializer = FundInfoSerializer(funds, many=True)
        
        return Response({
            'results': serializer.data,
            'total_count': total_count,
            'page': page,
            'page_size': page_size,
            'total_pages': (total_count + page_size - 1) // page_size
        })
    
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)


@api_view(['GET'])
@permission_classes([permissions.AllowAny])
def fund_statistics_test(request):
    """测试端点 - 不需要认证"""
    logger.info("fund_statistics_test API called - no auth required")
    return Response({'message': 'test successful', 'timestamp': timezone.now().isoformat()})

@csrf_exempt
def fund_statistics_django(request):
    """原生Django视图测试端点 - 绕过DRF认证"""
    if request.method == 'GET':
        logger.info("fund_statistics_django called - native Django view")
        return JsonResponse({
            'message': 'Django native view working',
            'timestamp': timezone.now().isoformat(),
            'method': request.method,
            'path': request.path
        })
    return JsonResponse({'error': 'Method not allowed'}, status=405)

@api_view(['GET'])
def fund_statistics(request):
    """基金统计信息"""
    return Response({
        'total_funds': 25102,
        'fund_types': 8,
        'fund_companies': 37,
        'latest_nav_count': 22428
    })


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def fund_performance(request, fund_code):
    """基金业绩分析"""
    try:
        fund = FundInfo.objects.get(fund_code=fund_code)
    except FundInfo.DoesNotExist:
        return Response({'error': '基金不存在'}, status=status.HTTP_404_NOT_FOUND)
    
    # 获取净值数据
    days = int(request.query_params.get('days', 365))
    start_date = timezone.now().date() - timedelta(days=days)
    
    net_values = FundNavDetail.objects.filter(
        fund_code=fund_code,
        nav_date__gte=start_date
    ).order_by('nav_date')
    
    if not net_values.exists():
        return Response({'error': '暂无净值数据'}, status=status.HTTP_404_NOT_FOUND)
    
    # 计算业绩指标
    latest_value = net_values.last()
    earliest_value = net_values.first()
    
    # 计算收益率
    if earliest_value and latest_value:
        period_return = (latest_value.unit_nav - earliest_value.unit_nav) / earliest_value.unit_nav
    else:
        period_return = 0
    
    # 计算波动率
    returns = []
    for i in range(1, len(net_values)):
        daily_return = (net_values[i].unit_nav - net_values[i-1].unit_nav) / net_values[i-1].unit_nav
        returns.append(daily_return)
    
    if returns:
        import statistics
        volatility = statistics.stdev(returns) * (252 ** 0.5)  # 年化波动率
        max_drawdown = min(returns) if returns else 0
    else:
        volatility = 0
        max_drawdown = 0
    
    # 计算夏普比率（假设无风险利率为3%）
    risk_free_rate = 0.03
    if volatility > 0:
        sharpe_ratio = (period_return * 365 / days - risk_free_rate) / volatility
    else:
        sharpe_ratio = 0
    
    return Response({
        'fund_code': fund_code,
        'fund_name': fund.fund_name,
        'period_days': days,
        'period_return': period_return,
        'annualized_return': period_return * 365 / days,
        'volatility': volatility,
        'sharpe_ratio': sharpe_ratio,
        'max_drawdown': max_drawdown,
        'latest_net_value': latest_value.unit_nav if latest_value else None,
        'latest_date': latest_value.nav_date if latest_value else None,
        'data_points': len(net_values)
    })


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def market_indicators(request):
    """市场指标概览"""
    # 获取最新的市场数据
    latest_date = MarketData.objects.aggregate(Max('data_date'))['data_date__max']
    
    if not latest_date:
        return Response({'error': '暂无市场数据'}, status=status.HTTP_404_NOT_FOUND)
    
    latest_data = MarketData.objects.filter(data_date=latest_date)
    
    indicators = {}
    for data in latest_data:
        indicators[data.indicator_type] = {
            'value': data.indicator_value,
            'change': data.change_value,
            'change_percent': data.change_percent,
            'date': data.data_date
        }
    
    return Response({
        'date': latest_date,
        'indicators': indicators,
        'total_indicators': len(indicators)
    })


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def sync_status(request):
    """数据同步状态"""
    # 获取最近的同步任务
    recent_tasks = DataSyncTask.objects.all().order_by('-created_at')[:10]
    
    # 统计同步状态
    total_tasks = DataSyncTask.objects.count()
    success_tasks = DataSyncTask.objects.filter(status='completed').count()
    failed_tasks = DataSyncTask.objects.filter(status='failed').count()
    running_tasks = DataSyncTask.objects.filter(status='running').count()
    
    # 获取最新数据时间 - 使用Raw SQL查询fund_nav_detail表
    from django.db import connection
    with connection.cursor() as cursor:
        cursor.execute("SELECT MAX(nav_date) FROM fund_nav_detail")
        result = cursor.fetchone()
        latest_fund_data = result[0] if result else None
    latest_market_data = MarketData.objects.aggregate(Max('data_date'))['data_date__max']
    
    return Response({
        'total_tasks': total_tasks,
        'success_tasks': success_tasks,
        'failed_tasks': failed_tasks,
        'running_tasks': running_tasks,
        'success_rate': success_tasks / total_tasks if total_tasks > 0 else 0,
        'latest_fund_data': latest_fund_data,
        'latest_market_data': latest_market_data,
        'recent_tasks': DataSyncTaskSerializer(recent_tasks, many=True).data
    })


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def download_fund_list(request):
    """
    下载基金清单
    """
    try:
        from .tasks import download_fund_list_task
        from celery import Task
        
        # 获取或创建默认数据源
        data_source, created = DataSource.objects.get_or_create(
            name='AKShare',
            defaults={
                'source_type': 'api',
                'is_active': True
            }
        )
        
        # 创建同步任务
        task = DataSyncTask.objects.create(
            name=f'基金清单下载_{timezone.now().strftime("%Y%m%d_%H%M%S")}',
            data_source=data_source,
            sync_type='fund_list',
            status='pending'
        )
        
        # 启动异步任务
        task_func: Task = download_fund_list_task
        task_func.delay(task.id)
        
        return Response({
            'success': True,
            'message': '基金清单下载任务已启动',
            'task_id': task.id
        })
        
    except Exception as e:
        logger.error(f"启动基金清单下载任务失败: {e}")
        return Response({
            'success': False,
            'message': f'启动任务失败: {str(e)}'
        }, status=500)


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def download_fund_details(request):
    """
    下载基金详细信息
    """
    try:
        from .tasks import download_fund_details_task
        from celery import Task
        
        fund_codes = request.data.get('fund_codes', [])
        
        # 获取或创建默认数据源
        data_source, created = DataSource.objects.get_or_create(
            name='AKShare',
            defaults={
                'source_type': 'api',
                'description': 'AKShare数据源',
                'is_active': True
            }
        )
        
        # 创建同步任务
        task = DataSyncTask.objects.create(
            name=f'基金详细信息下载_{timezone.now().strftime("%Y%m%d_%H%M%S")}',
            data_source=data_source,
            sync_type='fund_details',
            status='pending'
        )
        
        # 启动异步任务
        task_func: Task = download_fund_details_task
        task_func.delay(task.id, fund_codes)
        
        return Response({
            'success': True,
            'message': '基金详细信息下载任务已启动',
            'task_id': task.id
        })
        
    except Exception as e:
        logger.error(f"启动基金详细信息下载任务失败: {e}")
        return Response({
            'success': False,
            'message': f'启动任务失败: {str(e)}'
        }, status=500)


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def download_fund_nav(request):
    """
    下载基金净值
    """
    try:
        from .tasks import download_fund_nav_task
        from celery import Task
        
        fund_codes = request.data.get('fund_codes', [])
        
        # 获取或创建默认数据源
        data_source, created = DataSource.objects.get_or_create(
            name='AKShare',
            defaults={
                'source_type': 'api',
                'description': 'AKShare数据源',
                'is_active': True
            }
        )
        
        # 创建同步任务
        task = DataSyncTask.objects.create(
            name=f'基金净值下载_{timezone.now().strftime("%Y%m%d_%H%M%S")}',
            data_source=data_source,
            sync_type='fund_nav',
            status='pending'
        )
        
        # 启动异步任务
        task_func: Task = download_fund_nav_task
        task_func.delay(task.id, fund_codes)
        
        return Response({
            'success': True,
            'message': '基金净值下载任务已启动',
            'task_id': task.id
        })
        
    except Exception as e:
        logger.error(f"启动基金净值下载任务失败: {e}")
        return Response({
            'success': False,
            'message': f'启动任务失败: {str(e)}'
        }, status=500)


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def stop_download_task(request):
    """
    停止下载任务
    """
    try:
        task_id = request.data.get('task_id')
        if not task_id:
            return Response({
                'success': False,
                'message': '缺少task_id参数'
            }, status=400)
        
        # 查找任务
        try:
            task = DataSyncTask.objects.get(id=task_id)
        except DataSyncTask.DoesNotExist:
            return Response({
                'success': False,
                'message': '任务不存在'
            }, status=404)
        
        # 检查任务状态
        if task.status not in ['pending', 'running']:
            return Response({
                'success': False,
                'message': f'任务状态为{task.status}，无法停止'
            }, status=400)
        
        # 更新任务状态为已取消
        task.status = 'cancelled'
        task.completed_at = timezone.now()
        task.save()
        
        # 记录日志
        DataSyncLog.objects.create(
            task=task,
            level='INFO',
            message='任务已被用户手动停止'
        )
        
        logger.info(f"任务 {task_id} 已被停止")
        
        return Response({
            'success': True,
            'message': '任务已停止',
            'task_id': task_id
        })
        
    except Exception as e:
        logger.error(f"停止任务失败: {e}")
        return Response({
            'success': False,
            'message': f'停止任务失败: {str(e)}'
        }, status=500)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def export_fund_data(request):
    """导出基金数据为Excel文件"""
    try:
        
        # 获取查询参数
        start_date = request.query_params.get('start_date')
        end_date = request.query_params.get('end_date')
        code = request.query_params.get('code')
        
        # 构建查询
        queryset = FundInfo.objects.all()
        
        if start_date:
            queryset = queryset.filter(price_date__gte=start_date)
        if end_date:
            queryset = queryset.filter(price_date__lte=end_date)
        if code:
            queryset = queryset.filter(code=code)
            
        # 转换为DataFrame
        data = list(queryset.values(
            'code', 'name', 'net_value', 'accumulated_value', 
            'daily_return', 'price_date', 'updated_at'
        ))
        
        if not data:
            return Response({
                'status': 'error',
                'message': '没有找到符合条件的数据'
            }, status=status.HTTP_404_NOT_FOUND)
            
        df = pd.DataFrame(data)
        
        # 重命名列
        df.columns = ['基金代码', '基金名称', '单位净值', '累计净值', '日收益率', '价格日期', '更新时间']
        
        # 创建Excel文件
        output = io.BytesIO()
        with pd.ExcelWriter(output, engine='openpyxl') as writer:
            df.to_excel(writer, sheet_name='基金数据', index=False)
        
        output.seek(0)
        
        # 创建HTTP响应
        response = HttpResponse(
            output.getvalue(),
            content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        )
        response['Content-Disposition'] = f'attachment; filename="fund_data_{timezone.now().strftime("%Y%m%d")}.xlsx"'
        
        return response
        
    except Exception as e:
        logger.error(f"导出基金数据失败: {e}")
        return Response({
            'status': 'error',
            'message': f'导出失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def download_fund_basic_info(request):
    """下载基金基本信息"""
    try:
        fund_code = request.data.get('fund_code')
        if not fund_code:
            return Response({
                'status': 'error',
                'message': '基金代码不能为空'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # 使用AKShare服务获取基金基本信息
        fund_info = akshare_service.fetch_fund_basic_info_xq(fund_code)
        
        if not fund_info:
            return Response({
                'status': 'error',
                'message': f'未获取到基金 {fund_code} 的基本信息'
            }, status=status.HTTP_404_NOT_FOUND)
        
        # 获取当前日期
        current_date = timezone.now().date()
        
        # 获取默认产品（如果没有则创建）
        from products.models import Product, ProductCategory
        from datetime import date
        
        # 创建默认分类
        default_category, _ = ProductCategory.objects.get_or_create(
            code='DEFAULT',
            defaults={
                'name': '默认分类',
                'description': '系统默认产品分类'
            }
        )
        
        # 创建默认产品
        default_product, _ = Product.objects.get_or_create(
            code='DEFAULT_FUND',
            defaults={
                'name': '默认基金产品',
                'category': default_category,
                'product_type': 'balanced',
                'risk_level': 3,
                'manager': '默认基金经理',
                'company': '默认基金公司',
                'establishment_date': date.today(),
                'management_fee': 0.015,
                'custody_fee': 0.0025,
                'subscription_fee': 0.015,
                'redemption_fee': 0.005,
            }
        )
        
        # 保存到数据库
        fund, created = FundInfo.objects.update_or_create(
            fund_code=fund_code,
            defaults={
                'fund_name': fund_info.get('fund_name', ''),
                'fund_type': fund_info.get('fund_type', ''),
                'fund_company': fund_info.get('fund_company', ''),
                'fund_manager': fund_info.get('fund_manager', ''),
                'establishment_date': fund_info.get('establishment_date'),
                'fund_size': fund_info.get('fund_size'),
            }
        )
        
        action = '创建' if created else '更新'
        logger.info(f"成功{action}基金 {fund_code} 的基本信息")
        
        return Response({
            'status': 'success',
            'message': f'成功{action}基金基本信息',
            'data': fund_info
        })
        
    except Exception as e:
        logger.error(f"下载基金基本信息失败: {e}")
        return Response({
            'status': 'error',
            'message': f'下载失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])

@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def sync_fund_data(request):
    """
    同步基金数据API
    
    支持批量同步指定基金的基本信息和净值数据
    
    请求参数:
    - fund_codes: 基金代码列表 (可选，默认同步所有基金)
    - sync_net_value: 是否同步净值数据 (默认True)
    - force_update: 是否强制更新已存在的数据 (默认False)
    
    返回:
    - status: 同步状态 (success/error)
    - message: 状态消息
    - data: 同步结果统计
    """
    try:
        # 获取请求参数
        fund_codes = request.data.get('fund_codes', [])
        sync_net_value = request.data.get('sync_net_value', True)
        force_update = request.data.get('force_update', False)
        
        logger.info(f"开始同步基金数据: fund_codes={fund_codes}, sync_net_value={sync_net_value}")
        
        # 如果没有指定基金代码，获取所有基金列表
        if not fund_codes:
            try:
                fund_list = akshare_service.fetch_fund_list()
                if fund_list:
                    fund_codes = [fund['fund_code'] for fund in fund_list[:100]]  # 限制前100个基金
                    logger.info(f"获取到 {len(fund_codes)} 个基金代码")
                else:
                    return Response({
                        'status': 'error',
                        'message': '无法获取基金列表'
                    }, status=status.HTTP_400_BAD_REQUEST)
            except Exception as e:
                logger.error(f"获取基金列表失败: {e}")
                return Response({
                    'status': 'error',
                    'message': f'获取基金列表失败: {str(e)}'
                }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        
        # 执行数据同步
        sync_result = akshare_service.sync_fund_data(
            fund_codes=fund_codes,
            sync_net_value=sync_net_value
        )
        
        logger.info(f"基金数据同步完成: {sync_result}")
        
        return Response({
            'status': 'success',
            'message': '基金数据同步完成',
            'data': {
                'total_funds': len(fund_codes),
                'success_count': sync_result.get('success', 0),
                'error_count': sync_result.get('error', 0),
                'sync_net_value': sync_net_value,
                'force_update': force_update
            }
        })
        
    except Exception as e:
        logger.error(f"同步基金数据失败: {e}")
        return Response({
            'status': 'error',
            'message': f'同步失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def fund_net_value_latest(request, fund_code):
    """
    获取指定基金的最新净值数据
    
    参数:
    - fund_code: 基金代码
    
    返回:
    - 最新的净值数据
    """
    try:
        # 获取最新净值数据
        latest_nav = FundNavDetail.objects.filter(
            fund_code=fund_code
        ).order_by('-nav_date').first()
        
        if not latest_nav:
            return Response({
                'status': 'error',
                'message': f'未找到基金 {fund_code} 的净值数据'
            }, status=status.HTTP_404_NOT_FOUND)
        
        serializer = FundNavDetailSerializer(latest_nav)
        
        return Response({
            'status': 'success',
            'data': serializer.data
        })
        
    except Exception as e:
        logger.error(f"获取基金最新净值失败: {e}")
        return Response({
            'status': 'error',
            'message': f'获取失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def refresh_fund_net_value(request, fund_code):
    """
    刷新指定基金的净值数据
    
    参数:
    - fund_code: 基金代码
    
    返回:
    - 刷新结果统计
    """
    try:
        logger.info(f"开始刷新基金 {fund_code} 的净值数据")
        
        # 获取净值数据
        net_values = akshare_service.fetch_fund_net_value(fund_code)
        
        if not net_values:
            return Response({
                'status': 'error',
                'message': f'无法获取基金 {fund_code} 的净值数据'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # 同步净值数据
        saved_count = akshare_service.sync_fund_net_values(fund_code, net_values)
        
        logger.info(f"基金 {fund_code} 净值数据刷新完成，保存 {saved_count} 条记录")
        
        return Response({
            'status': 'success',
            'message': '净值数据刷新完成',
            'data': {
                'fund_code': fund_code,
                'total_records': len(net_values),
                'saved_count': saved_count
            }
        })
        
    except Exception as e:
        logger.error(f"刷新基金净值数据失败: {e}")
        return Response({
            'status': 'error',
            'message': f'刷新失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def download_progress(request):
    """
    获取基金数据下载进展
    
    返回:
    - 基金清单、基金详细信息、基金净值的下载进展统计
    """
    try:
        # 检查是否有正在运行的任务
        running_fund_list_task = DataSyncTask.objects.filter(
            sync_type='fund_list',
            status='running'
        ).first()
        
        running_fund_detail_task = DataSyncTask.objects.filter(
            sync_type='fund_details',
            status='running'
        ).first()
        
        running_fund_nav_task = DataSyncTask.objects.filter(
            sync_type='fund_nav',
            status='running'
        ).first()
        
        # 获取基金清单进展
        fund_list_downloaded = FundInfo.objects.count()
        fund_list_total = fund_list_downloaded if fund_list_downloaded > 0 else 0
        
        # 获取基金详细信息进展
        fund_detail_total = fund_list_downloaded
        fund_detail_downloaded = FundInfoDetail.objects.count()
        
        # 获取基金净值进展
        fund_nav_total = fund_list_downloaded
        # 获取有净值数据的基金数量
        fund_codes_with_nav = FundNavDetail.objects.values_list('fund_code', flat=True).distinct()
        fund_nav_downloaded = FundInfo.objects.filter(
            fund_code__in=fund_codes_with_nav
        ).count()
        
        # 计算进度百分比
        fund_list_progress = 100 if fund_list_total == 0 else min(100, (fund_list_downloaded / max(1, fund_list_total)) * 100)
        fund_detail_progress = 100 if fund_detail_total == 0 else min(100, (fund_detail_downloaded / max(1, fund_detail_total)) * 100)
        fund_nav_progress = 100 if fund_nav_total == 0 else min(100, (fund_nav_downloaded / max(1, fund_nav_total)) * 100)
        
        # 确定状态：如果有正在运行的任务，状态为downloading；否则根据进度判断
        fund_list_status = 'downloading' if running_fund_list_task else ('completed' if fund_list_progress >= 100 else 'idle')
        fund_detail_status = 'downloading' if running_fund_detail_task else ('completed' if fund_detail_progress >= 100 else 'idle')
        fund_nav_status = 'downloading' if running_fund_nav_task else ('completed' if fund_nav_progress >= 100 else 'idle')
        
        # 获取最后更新时间
        last_fund_update = FundInfo.objects.aggregate(Max('updated_at'))['updated_at__max']
        last_nav_update = FundNavDetail.objects.aggregate(Max('updated_at'))['updated_at__max']
        
        return Response({
            'status': 'success',
            'data': {
                'fund_list': {
                    'total': fund_list_total,
                    'downloaded': fund_list_downloaded,
                    'progress': round(fund_list_progress, 1),
                    'status': fund_list_status,
                    'last_updated': last_fund_update,
                    'task_id': running_fund_list_task.id if running_fund_list_task else None
                },
                'fund_detail': {
                    'total': fund_detail_total,
                    'downloaded': fund_detail_downloaded,
                    'progress': round(fund_detail_progress, 1),
                    'status': fund_detail_status,
                    'last_updated': last_fund_update,
                    'task_id': running_fund_detail_task.id if running_fund_detail_task else None
                },
                'fund_nav': {
                    'total': fund_nav_total,
                    'downloaded': fund_nav_downloaded,
                    'progress': round(fund_nav_progress, 1),
                    'status': fund_nav_status,
                    'last_updated': last_nav_update,
                    'task_id': running_fund_nav_task.id if running_fund_nav_task else None
                }
            }
        })
        
    except Exception as e:
        logger.error(f"获取下载进展失败: {e}")
        return Response({
            'status': 'error',
            'message': f'获取进展失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def update_fund_list(request):
    """
    更新基金清单数据
    
    返回:
    - 更新结果统计
    """
    try:
        logger.info("开始更新基金清单数据")
        
        # 获取基金列表
        fund_list = akshare_service.fetch_fund_list()
        
        if not fund_list:
            return Response({
                'status': 'error',
                'message': '无法获取基金列表数据'
            }, status=status.HTTP_400_BAD_REQUEST)
        
        # 同步基金列表数据
        updated_count = 0
        created_count = 0
        
        for fund_data in fund_list:
            fund_code = fund_data.get('fund_code')
            if not fund_code:
                continue
                
            fund_info, created = FundInfo.objects.update_or_create(
                fund_code=fund_code,
                defaults={
                    'fund_name': fund_data.get('fund_name', ''),
                    'fund_type': fund_data.get('fund_type', ''),
                    'updated_at': timezone.now()
                }
            )
            
            if created:
                created_count += 1
            else:
                updated_count += 1
        
        logger.info(f"基金清单更新完成: 新增 {created_count} 个，更新 {updated_count} 个")
        
        return Response({
            'status': 'success',
            'message': '基金清单更新完成',
            'data': {
                'total_processed': len(fund_list),
                'created_count': created_count,
                'updated_count': updated_count
            }
        })
        
    except Exception as e:
        logger.error(f"更新基金清单失败: {e}")
        return Response({
            'status': 'error',
            'message': f'更新失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 全局基金净值爬虫实例
_fund_nav_scraper_instance = None

def get_fund_nav_scraper():
    """获取基金净值爬虫实例"""
    global _fund_nav_scraper_instance
    if _fund_nav_scraper_instance is None:
        import sys
        import os
        # 添加fund_nav_scraper.py所在目录到Python路径
        current_dir = os.path.dirname(os.path.abspath(__file__))
        parent_dir = os.path.dirname(current_dir)
        sys.path.insert(0, parent_dir)
        
        from fund_nav_scraper import FundNavScraper
        # 从配置文件获取数据库配置
        db_config = get_database_config()
        _fund_nav_scraper_instance = FundNavScraper(db_config)
    return _fund_nav_scraper_instance

@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def start_fund_nav_download(request):
    """
    开始基金净值下载
    """
    try:
        limit = request.data.get('limit', None)
        if limit is not None:
            limit = int(limit)
        
        scraper = get_fund_nav_scraper()
        
        # 检查当前状态
        if scraper.status.value == 'downloading':
            return Response({
                'success': False,
                'message': '基金净值下载任务正在进行中，请等待完成或先停止当前任务'
            }, status=400)
        
        # 在后台线程中启动下载
        import threading
        def download_task():
            try:
                scraper.download_all_fund_nav(limit)
            except Exception as e:
                logger.error(f"基金净值下载任务执行失败: {e}")
        
        thread = threading.Thread(target=download_task)
        thread.daemon = True
        thread.start()
        
        return Response({
            'success': True,
            'message': f'基金净值下载任务已启动，限制数量: {limit or "无限制"}'
        })
        
    except Exception as e:
        logger.error(f"启动基金净值下载失败: {e}")
        return Response({
            'success': False,
            'message': f'启动失败: {str(e)}'
        }, status=500)

@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def stop_fund_nav_download(request):
    """
    停止基金净值下载
    """
    try:
        scraper = get_fund_nav_scraper()
        
        if scraper.stop_download():
            return Response({
                'success': True,
                'message': '基金净值下载停止请求已发送'
            })
        else:
            return Response({
                'success': False,
                'message': f'当前状态 {scraper.status.value} 不支持停止操作'
            }, status=400)
            
    except Exception as e:
        logger.error(f"停止基金净值下载失败: {e}")
        return Response({
            'success': False,
            'message': f'停止失败: {str(e)}'
        }, status=500)

@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def continue_fund_nav_download(request):
    """
    断点续传基金净值下载
    """
    try:
        limit = request.data.get('limit', None)
        if limit is not None:
            limit = int(limit)
        
        scraper = get_fund_nav_scraper()
        
        # 检查当前状态
        if scraper.status.value == 'downloading':
            return Response({
                'success': False,
                'message': '基金净值下载任务正在进行中，无需重复启动'
            }, status=400)
        
        # 在后台线程中启动断点续传
        import threading
        def continue_task():
            try:
                scraper.continue_download(limit)
            except Exception as e:
                logger.error(f"基金净值断点续传任务执行失败: {e}")
        
        thread = threading.Thread(target=continue_task)
        thread.daemon = True
        thread.start()
        
        return Response({
            'success': True,
            'message': f'基金净值断点续传任务已启动，限制数量: {limit or "无限制"}'
        })
        
    except Exception as e:
        logger.error(f"启动基金净值断点续传失败: {e}")
        return Response({
            'success': False,
            'message': f'启动失败: {str(e)}'
        }, status=500)

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def get_fund_nav_download_status(request):
    """
    获取基金净值下载状态
    """
    try:
        scraper = get_fund_nav_scraper()
        progress_info = scraper.get_progress_info()
        
        return Response({
            'success': True,
            'data': progress_info
        })
        
    except Exception as e:
        logger.error(f"获取基金净值下载状态失败: {e}")
        return Response({
            'success': False,
            'message': f'获取状态失败: {str(e)}'
        }, status=500)

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def get_fund_nav_download_statistics(request):
    """
    获取基金净值下载统计信息
    """
    try:
        scraper = get_fund_nav_scraper()
        stats = scraper.get_download_statistics()
        
        return Response({
            'success': True,
            'data': stats
        })
        
    except Exception as e:
        logger.error(f"获取基金净值下载统计失败: {e}")
        return Response({
            'success': False,
            'message': f'获取统计失败: {str(e)}'
        }, status=500)

@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def reset_fund_nav_download(request):
    """
    重置基金净值下载状态，强制清理所有状态用于新下载
    """
    try:
        scraper = get_fund_nav_scraper()
        
        # 强制重置状态
        if scraper.force_reset_for_new_download():
            return Response({
                'success': True,
                'message': '基金净值下载状态已重置，可以开始新的下载任务'
            })
        else:
            return Response({
                'success': False,
                'message': '重置失败，请稍后重试'
            }, status=500)
            
    except Exception as e:
        logger.error(f"重置基金净值下载状态失败: {e}")
        return Response({
            'success': False,
            'message': f'重置失败: {str(e)}'
        }, status=500)

@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def restart_fund_nav_download(request):
    """
    重新启动基金净值下载（仅在允许的状态下）
    """
    try:
        limit = request.data.get('limit', None)
        if limit is not None:
            limit = int(limit)
        
        scraper = get_fund_nav_scraper()
        
        # 检查是否可以重新启动
        can_restart, status_message = scraper.can_restart_download()
        
        if not can_restart:
            return Response({
                'success': False,
                'message': status_message,
                'current_status': scraper.status.value
            }, status=400)
        
        # 在后台线程中启动下载
        import threading
        def download_task():
            try:
                scraper.download_all_fund_nav(limit)
            except Exception as e:
                logger.error(f"重新启动基金净值下载任务执行失败: {e}")
        
        thread = threading.Thread(target=download_task)
        thread.daemon = True
        thread.start()
        
        return Response({
            'success': True,
            'message': f'基金净值下载任务已重新启动，限制数量: {limit or "无限制"}'
        })
        
    except Exception as e:
        logger.error(f"重新启动基金净值下载失败: {e}")
        return Response({
            'success': False,
            'message': f'重新启动失败: {str(e)}'
        }, status=500)


# 全局下载器实例，用于状态管理
_fund_downloader_instance = None

def get_fund_downloader():
    """获取全局基金下载器实例"""
    global _fund_downloader_instance
    if _fund_downloader_instance is None:
        _fund_downloader_instance = FundDataDownloader()
    return _fund_downloader_instance

@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def update_fund_detail(request):
    """
    更新基金详细信息
    
    参数:
    - force: 是否强制更新所有基金详细信息
    - limit: 限制更新的基金数量
    
    返回:
    - 更新结果统计和任务ID
    """
    try:
        logger.info("开始更新基金详细信息")
        
        # 检查是否强制更新
        force_update = request.data.get('force', False)
        limit = request.data.get('limit', None)
        
        # 获取全局下载器实例
        downloader = get_fund_downloader()
        
        # 检查当前状态
        progress_info = downloader.get_progress_info()
        current_status = progress_info.get('status')
        
        # 如果正在下载，返回当前状态
        if current_status == 'DOWNLOADING':
            return Response({
                'status': 'success',
                'message': '基金详细信息下载任务正在进行中',
                'data': {
                    'task_id': id(downloader),  # 使用下载器实例ID作为任务ID
                    'current_status': current_status,
                    'progress': progress_info
                }
            })
        
        # 重置停止标志（如果之前被停止）
        if downloader.is_stopped():
            downloader.reset()
        
        # 启动下载任务（异步）
        import threading
        def download_task():
            try:
                downloader.download_fund_details(limit=limit)
            except Exception as e:
                logger.error(f"后台下载任务失败: {e}")
        
        # 在后台线程中启动下载
        download_thread = threading.Thread(target=download_task, daemon=True)
        download_thread.start()
        
        # 返回任务启动成功的响应
        return Response({
            'status': 'success',
            'message': '基金详细信息下载任务已启动',
            'data': {
                'task_id': id(downloader),  # 使用下载器实例ID作为任务ID
                'current_status': 'DOWNLOADING',
                'progress': downloader.get_progress_info()
            }
        })
        
    except Exception as e:
        logger.error(f"启动基金详细信息下载失败: {e}")
        return Response({
            'status': 'error',
            'message': f'启动下载失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def check_database_data(request):
    """
    检查数据库中基金数据的存在情况
    
    返回:
    - 基金列表数据统计
    - 基金详细信息数据统计
    """
    try:
        # 检查基金列表数据
        fund_list_count = FundInfo.objects.count()
        
        # 检查基金详细信息数据（有fund_name的记录）
        fund_detail_count = FundInfo.objects.filter(
            fund_name__isnull=False,
            fund_name__gt=''
        ).count()
        
        # 检查基金净值数据
        fund_nav_count = FundNavDetail.objects.count()
        
        # 获取最后更新时间
        latest_fund_update = None
        latest_nav_update = None
        
        if fund_list_count > 0:
            latest_fund = FundInfo.objects.order_by('-updated_at').first()
            latest_fund_update = latest_fund.updated_at if latest_fund else None
            
        if fund_nav_count > 0:
            latest_nav = FundNavDetail.objects.order_by('-updated_at').first()
            latest_nav_update = latest_nav.updated_at if latest_nav else None
        
        return Response({
            'status': 'success',
            'data': {
                'fund_list': {
                    'count': fund_list_count,
                    'has_data': fund_list_count > 0,
                    'last_updated': latest_fund_update
                },
                'fund_details': {
                    'count': fund_detail_count,
                    'has_data': fund_detail_count > 0,
                    'last_updated': latest_fund_update
                },
                'fund_nav': {
                    'count': fund_nav_count,
                    'has_data': fund_nav_count > 0,
                    'last_updated': latest_nav_update
                }
            }
        })
        
    except Exception as e:
        logger.error(f"检查数据库数据失败: {e}")
        return Response({
            'status': 'error',
            'message': f'检查数据库数据失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['DELETE'])
@permission_classes([permissions.IsAuthenticated])
def clear_fund_data(request):
    """
    清空基金数据
    
    参数:
    - data_type: 数据类型 ('fund_list', 'fund_details', 'fund_nav', 'all')
    
    返回:
    - 删除结果统计
    """
    try:
        data_type = request.data.get('data_type', 'all')
        
        deleted_counts = {
            'fund_list': 0,
            'fund_details': 0,
            'fund_nav': 0
        }
        
        if data_type in ['fund_list', 'all']:
            # 删除基金列表数据
            fund_count = FundInfo.objects.count()
            FundInfo.objects.all().delete()
            deleted_counts['fund_list'] = fund_count
            logger.info(f"已删除 {fund_count} 条基金列表数据")
            
        elif data_type == 'fund_details':
            # 只清空详细信息字段，保留基本信息
            fund_count = FundInfo.objects.filter(
                fund_full_name__isnull=False,
                fund_full_name__gt=''
            ).count()
            
            FundInfo.objects.update(
                fund_full_name=None,
                fund_manager=None,
                custodian_bank=None,
                fund_size=None,
                investment_strategy=None,
                investment_objective=None,
                performance_benchmark=None,
                rating_agency=None,
                fund_rating=None
            )
            deleted_counts['fund_details'] = fund_count
            logger.info(f"已清空 {fund_count} 条基金详细信息")
            
        if data_type in ['fund_nav', 'all']:
            # 删除基金净值数据 - 使用更高效的方式
            from django.db import connection
            
            # 先获取记录数量（如果数据量很大，这个操作可能也会很慢，所以我们跳过计数）
            logger.info("开始清空基金净值数据...")
            
            # 使用原生SQL进行快速删除，避免Django ORM的开销
            with connection.cursor() as cursor:
                cursor.execute("DELETE FROM fund_nav_detail")
                nav_count = cursor.rowcount
                
            deleted_counts['fund_nav'] = nav_count
            logger.info(f"已删除 {nav_count} 条基金净值数据")
        
        return Response({
            'success': True,
            'message': f'成功清空 {data_type} 数据',
            'data': {
                'deleted_counts': deleted_counts,
                'data_type': data_type
            }
        })
        
    except Exception as e:
        logger.error(f"清空基金数据失败: {e}")
        return Response({
            'success': False,
            'message': f'清空基金数据失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def update_fund_nav(request):
    """
    更新基金净值数据
    
    返回:
    - 更新结果统计
    """
    try:
        logger.info("开始更新基金净值数据")
        
        # 获取需要更新净值的基金列表
        # 由于没有外键关联，使用子查询方式
        
        # 查找没有净值记录或净值数据过期的基金
        has_recent_nav = FundNavDetail.objects.filter(
            fund_code=OuterRef('fund_code'),
            nav_date__gte=timezone.now().date() - timedelta(days=1)
        )
        
        funds_to_update = FundInfo.objects.filter(
            ~Exists(has_recent_nav)
        ).distinct()[:20]  # 限制每次更新20个
        
        if not funds_to_update.exists():
            return Response({
                'status': 'success',
                'message': '所有基金净值数据已是最新',
                'data': {
                    'updated_count': 0
                }
            })
        
        updated_count = 0
        error_count = 0
        total_nav_records = 0
        
        for fund in funds_to_update:
            try:
                # 获取基金净值数据
                net_values = akshare_service.fetch_fund_net_value(fund.fund_code)
                
                if net_values:
                    saved_count = akshare_service.sync_fund_net_values(fund.fund_code, net_values)
                    total_nav_records += saved_count
                    updated_count += 1
                else:
                    error_count += 1
                    
            except Exception as e:
                logger.error(f"更新基金 {fund.fund_code} 净值数据失败: {e}")
                error_count += 1
        
        logger.info(f"基金净值数据更新完成: 更新 {updated_count} 个基金，共 {total_nav_records} 条净值记录，失败 {error_count} 个")
        
        return Response({
            'status': 'success',
            'message': '基金净值数据更新完成',
            'data': {
                'updated_funds': updated_count,
                'total_nav_records': total_nav_records,
                'error_count': error_count
            }
        })
        
    except Exception as e:
        logger.error(f"更新基金净值数据失败: {e}")
        return Response({
            'status': 'error',
            'message': f'更新失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# ==================== 基金净值更新API ====================

# 基金净值更新状态管理
fund_nav_update_status = {
    'status': 'idle',  # idle, running, completed, failed
    'start_time': None,
    'end_time': None,
    'current_fund': None,
    'progress': {
        'total_funds': 0,
        'processed_funds': 0,
        'updated_funds': 0,
        'failed_funds': 0,
        'total_nav_records': 0
    },
    'message': '',
    'task_id': None
}

@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def start_fund_nav_update(request):
    """
    开始基金净值更新任务
    """
    try:
        global fund_nav_update_status
        
        # 检查当前状态
        if fund_nav_update_status['status'] == 'running':
            return Response({
                'success': False,
                'message': '基金净值更新任务正在进行中，请等待完成或先停止当前任务'
            }, status=400)
        
        # 重置状态
        fund_nav_update_status.update({
            'status': 'running',
            'start_time': timezone.now(),
            'end_time': None,
            'current_fund': None,
            'progress': {
                'total_funds': 0,
                'processed_funds': 0,
                'updated_funds': 0,
                'failed_funds': 0,
                'total_nav_records': 0
            },
            'message': '正在启动基金净值更新任务...',
            'task_id': f"nav_update_{int(timezone.now().timestamp())}"
        })
        
        # 在后台线程中启动更新任务
        import threading
        def update_task():
            try:
                _execute_fund_nav_update()
            except Exception as e:
                logger.error(f"基金净值更新任务执行失败: {e}")
                fund_nav_update_status.update({
                    'status': 'failed',
                    'end_time': timezone.now(),
                    'message': f'更新失败: {str(e)}'
                })
        
        thread = threading.Thread(target=update_task)
        thread.daemon = True
        thread.start()
        
        return Response({
            'success': True,
            'message': '基金净值更新任务已启动',
            'task_id': fund_nav_update_status['task_id']
        })
        
    except Exception as e:
        logger.error(f"启动基金净值更新失败: {e}")
        return Response({
            'success': False,
            'message': f'启动失败: {str(e)}'
        }, status=500)

@api_view(['POST'])
@permission_classes([permissions.IsAuthenticated])
def stop_fund_nav_update(request):
    """
    停止基金净值更新任务
    """
    try:
        global fund_nav_update_status
        
        if fund_nav_update_status['status'] != 'running':
            return Response({
                'success': False,
                'message': f'当前状态 {fund_nav_update_status["status"]} 不支持停止操作'
            }, status=400)
        
        fund_nav_update_status.update({
            'status': 'idle',
            'end_time': timezone.now(),
            'message': '用户手动停止了更新任务'
        })
        
        return Response({
            'success': True,
            'message': '基金净值更新停止请求已发送'
        })
        
    except Exception as e:
        logger.error(f"停止基金净值更新失败: {e}")
        return Response({
            'success': False,
            'message': f'停止失败: {str(e)}'
        }, status=500)

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def get_fund_nav_update_status(request):
    """
    获取基金净值更新状态
    """
    try:
        global fund_nav_update_status
        
        return Response({
            'success': True,
            'data': {
                'status': fund_nav_update_status['status'],
                'start_time': fund_nav_update_status['start_time'],
                'end_time': fund_nav_update_status['end_time'],
                'current_fund': fund_nav_update_status['current_fund'],
                'progress': fund_nav_update_status['progress'],
                'message': fund_nav_update_status['message'],
                'task_id': fund_nav_update_status['task_id']
            }
        })
        
    except Exception as e:
        logger.error(f"获取基金净值更新状态失败: {e}")
        return Response({
            'success': False,
            'message': f'获取状态失败: {str(e)}'
        }, status=500)

@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def get_fund_nav_update_statistics(request):
    """
    获取基金净值更新统计信息
    """
    try:
        global fund_nav_update_status
        
        # 获取需要更新的基金总数
        has_recent_nav = FundNavDetail.objects.filter(
            fund_code=OuterRef('fund_code'),
            nav_date__gte=timezone.now().date() - timedelta(days=1)
        )
        
        total_funds_to_update = FundInfo.objects.filter(
            ~Exists(has_recent_nav)
        ).distinct().count()
        
        return Response({
            'success': True,
            'data': {
                'total_funds_to_update': total_funds_to_update,
                'progress': fund_nav_update_status['progress'],
                'status': fund_nav_update_status['status']
            }
        })
        
    except Exception as e:
        logger.error(f"获取基金净值更新统计失败: {e}")
        return Response({
            'success': False,
            'message': f'获取统计失败: {str(e)}'
        }, status=500)

def _execute_fund_nav_update():
    """
    执行基金净值更新任务的内部函数
    """
    global fund_nav_update_status
    
    try:
        logger.info("开始执行基金净值更新任务")
        
        # 获取需要更新净值的基金列表
        has_recent_nav = FundNavDetail.objects.filter(
            fund_code=OuterRef('fund_code'),
            nav_date__gte=timezone.now().date() - timedelta(days=1)
        )
        
        funds_to_update = FundInfo.objects.filter(
            ~Exists(has_recent_nav)
        ).distinct()
        
        total_funds = funds_to_update.count()
        
        if total_funds == 0:
            fund_nav_update_status.update({
                'status': 'completed',
                'end_time': timezone.now(),
                'message': '所有基金净值数据已是最新，无需更新'
            })
            return
        
        # 更新总数
        fund_nav_update_status['progress']['total_funds'] = total_funds
        fund_nav_update_status['message'] = f'开始更新 {total_funds} 个基金的净值数据'
        
        updated_count = 0
        error_count = 0
        total_nav_records = 0
        
        for i, fund in enumerate(funds_to_update):
            # 检查是否被停止
            if fund_nav_update_status['status'] != 'running':
                break
                
            try:
                fund_nav_update_status['current_fund'] = fund.fund_code
                fund_nav_update_status['message'] = f'正在更新基金 {fund.fund_code} ({i+1}/{total_funds})'
                
                # 获取基金净值数据
                net_values = akshare_service.fetch_fund_net_value(fund.fund_code)
                
                if net_values:
                    saved_count = akshare_service.sync_fund_net_values(fund.fund_code, net_values)
                    total_nav_records += saved_count
                    updated_count += 1
                else:
                    error_count += 1
                    
            except Exception as e:
                logger.error(f"更新基金 {fund.fund_code} 净值数据失败: {e}")
                error_count += 1
            
            # 更新进度
            fund_nav_update_status['progress'].update({
                'processed_funds': i + 1,
                'updated_funds': updated_count,
                'failed_funds': error_count,
                'total_nav_records': total_nav_records
            })
        
        # 任务完成
        if fund_nav_update_status['status'] == 'running':
            fund_nav_update_status.update({
                'status': 'completed',
                'end_time': timezone.now(),
                'message': f'基金净值更新完成: 更新 {updated_count} 个基金，共 {total_nav_records} 条净值记录，失败 {error_count} 个'
            })
        
        logger.info(f"基金净值更新任务完成: 更新 {updated_count} 个基金，共 {total_nav_records} 条净值记录，失败 {error_count} 个")
        
    except Exception as e:
        logger.error(f"执行基金净值更新任务失败: {e}")
        fund_nav_update_status.update({
            'status': 'failed',
            'end_time': timezone.now(),
            'message': f'更新失败: {str(e)}'
        })

# ==================== 基金排行数据API ====================

@api_view(['GET'])
@permission_classes([permissions.AllowAny])
def test_debug_endpoint(request):
    """
    全新的测试端点，用于验证API框架是否正常工作
    """
    return Response({
        'status': 'success',
        'message': 'Test debug endpoint is working',
        'timestamp': timezone.now().isoformat(),
        'request_method': request.method,
        'request_path': request.path
    })

@api_view(['GET'])
@permission_classes([permissions.AllowAny])
def fund_nav_ranking_stats(request):
    """
    获取基金净值排名统计数据
    
    参数:
    - page: 页码 (默认1)
    - page_size: 每页数量 (默认50)
    - nav_date: 净值日期 (可选，格式: YYYY-MM-DD)
    - sort_by: 排序字段 (daily_growth_rate, weekly_growth_rate等)
    - order: 排序方向 (asc, desc，默认desc)
    - fund_name: 基金名称模糊查询
    """
    
    try:
        import sys
        import os
        sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
        from data_service.final_fund_scraper import FinalFundScraper
        
        # 获取查询参数
        page = int(request.GET.get('page', 1))
        page_size = int(request.GET.get('page_size', 50))
        nav_date = request.GET.get('nav_date')
        sort_by = request.GET.get('sort_by', 'daily_growth_rate')
        order = request.GET.get('order', 'desc')
        fund_name = request.GET.get('fund_name')
        
        # 创建爬虫实例
        scraper = FinalFundScraper()
        
        # 调用API方法获取数据
        result = scraper.get_fund_data_for_api(
            page=page,
            page_size=page_size,
            nav_date=nav_date,
            sort_by=sort_by,
            order=order,
            fund_name=fund_name
        )
        
        if 'error' in result:
            return Response({
                'status': 'error',
                'message': result['error']
            }, status=500)
        
        # 获取可用日期列表
        available_dates = scraper.get_available_dates()
        
        # 计算统计信息
        stats = scraper.get_fund_ranking_statistics(nav_date)
        
        return Response({
            'status': 'success',
            'data': result.get('data', []),
            'pagination': result.get('pagination', {}),
            'statistics': {
                'available_dates': available_dates,
                'latest_update': result.get('latest_update'),
                'target_date': nav_date or (available_dates[0] if available_dates else None),
                'total_count': stats.get('total_count', 0),
                'avg_daily_growth_rate': stats.get('avg_daily_growth_rate', 0),
                'avg_yearly_return': stats.get('avg_yearly_return', 0),
                'avg_unit_nav': stats.get('avg_unit_nav', 0)
            },
            'query_params': {
                'page': page,
                'page_size': page_size,
                'nav_date': nav_date,
                'sort_by': sort_by,
                'order': order,
                'fund_name': fund_name
            }
        })
        
    except Exception as e:
        logger.error(f"获取基金排行数据失败: {e}")
        return Response({
            'status': 'error',
            'message': f'获取数据失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# 全局变量存储同步状态
fund_ranking_sync_status = {
    'status': 'idle',  # idle, running, completed, failed
    'start_time': None,
    'end_time': None,
    'process_id': None,
    'message': ''
}

@api_view(['POST'])
@permission_classes([permissions.AllowAny])
def sync_fund_nav_ranking(request):
    """
    同步基金排行数据
    
    触发基金排行数据的下载和同步
    """
    global fund_ranking_sync_status
    
    # 检查是否已有同步任务在运行
    if fund_ranking_sync_status['status'] == 'running':
        return Response({
            'status': 'error',
            'message': '数据同步正在进行中，请稍候...'
        }, status=status.HTTP_409_CONFLICT)
    
    try:
        # 导入基金排行爬虫
        import subprocess
        import os
        import threading
        
        # 使用现有的final_fund_scraper.py中的方法
        try:
            from .final_fund_scraper import FinalFundScraper
            
            def run_sync_process():
                try:
                    fund_ranking_sync_status.update({
                        'status': 'running',
                        'start_time': timezone.now(),
                        'end_time': None,
                        'process_id': None,
                        'message': '数据同步已启动'
                    })
                    
                    # 创建爬虫实例并运行
                    scraper = FinalFundScraper()
                    scraper.run(max_pages=None, save_excel=False, save_csv=False, save_database=True)
                    
                    # 检查是否有数据
                    if hasattr(scraper, 'all_data') and scraper.all_data:
                        fund_ranking_sync_status.update({
                            'status': 'completed',
                            'end_time': timezone.now(),
                            'message': f'数据同步完成，共获取 {len(scraper.all_data)} 条数据'
                        })
                    else:
                        fund_ranking_sync_status.update({
                            'status': 'failed',
                            'end_time': timezone.now(),
                            'message': '同步失败: 未获取到数据'
                        })
                        
                except Exception as e:
                    fund_ranking_sync_status.update({
                        'status': 'failed',
                        'end_time': timezone.now(),
                        'message': f'同步过程中出错: {str(e)}'
                    })
            
            # 在新线程中运行同步过程
            sync_thread = threading.Thread(target=run_sync_process)
            sync_thread.daemon = True
            sync_thread.start()
            
            return Response({
                'status': 'success',
                'message': '基金排行数据同步已启动',
                'timestamp': timezone.now().strftime('%Y-%m-%d %H:%M:%S')
            })
            
        except ImportError as e:
            return Response({
                'status': 'error',
                'message': f'导入爬虫模块失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
        
    except Exception as e:
        fund_ranking_sync_status.update({
            'status': 'failed',
            'end_time': timezone.now(),
            'message': f'同步失败: {str(e)}'
        })
        logger.error(f"同步基金排行数据失败: {e}")
        return Response({
            'status': 'error',
            'message': f'同步失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

@api_view(['GET'])
@permission_classes([permissions.AllowAny])
def sync_fund_nav_ranking_status(request):
    """
    获取基金排行数据同步状态
    """
    global fund_ranking_sync_status
    
    return Response({
        'status': fund_ranking_sync_status['status'],
        'start_time': fund_ranking_sync_status['start_time'].strftime('%Y-%m-%d %H:%M:%S') if fund_ranking_sync_status['start_time'] else None,
        'end_time': fund_ranking_sync_status['end_time'].strftime('%Y-%m-%d %H:%M:%S') if fund_ranking_sync_status['end_time'] else None,
        'process_id': fund_ranking_sync_status['process_id'],
        'message': fund_ranking_sync_status['message']
    })


class FundNavDetailListView(generics.ListAPIView):
    """基金历史净值明细列表视图"""
    serializer_class = FundNavDetailSerializer
    permission_classes = [permissions.IsAuthenticated]
    
    def get_queryset(self):
        """获取查询集，支持基金代码过滤，按基金代码分组显示最新数据"""
        queryset = FundNavDetail.objects.all()
        
        # 基金代码过滤
        fund_codes = self.request.query_params.get('fund_codes', None)
        if fund_codes:
            fund_code_list = [code.strip() for code in fund_codes.split(',') if code.strip()]
            if fund_code_list:
                queryset = queryset.filter(fund_code__in=fund_code_list)
        
        # 按基金代码分组，获取每个基金的最新净值数据
        latest_nav_subquery = FundNavDetail.objects.filter(
            fund_code=OuterRef('fund_code')
        ).order_by('-nav_date').values('id')[:1]
        
        queryset = queryset.filter(
            id__in=latest_nav_subquery
        ).order_by('fund_code')
        
        return queryset


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def fund_nav_detail_history(request, fund_code):
    """
    获取指定基金的历史净值数据
    支持时间范围过滤
    """
    try:
        # 获取查询参数
        start_date = request.GET.get('start_date')
        end_date = request.GET.get('end_date')
        period = request.GET.get('period', 'all')  # all, 10y, 5y, 3y, 1y, ytd
        
        # 构建查询条件
        queryset = FundNavDetail.objects.filter(fund_code=fund_code)
        
        # 根据period参数设置时间范围
        if period != 'all':
            end_date_obj = timezone.now().date()
            
            if period == '1y':
                start_date_obj = end_date_obj - timedelta(days=365)
            elif period == '3y':
                start_date_obj = end_date_obj - timedelta(days=365*3)
            elif period == '5y':
                start_date_obj = end_date_obj - timedelta(days=365*5)
            elif period == '10y':
                start_date_obj = end_date_obj - timedelta(days=365*10)
            elif period == 'ytd':
                start_date_obj = datetime(end_date_obj.year, 1, 1).date()
            else:
                start_date_obj = None
                
            if start_date_obj:
                queryset = queryset.filter(nav_date__gte=start_date_obj)
        
        # 自定义日期范围
        if start_date:
            try:
                start_date_obj = datetime.strptime(start_date, '%Y-%m-%d').date()
                queryset = queryset.filter(nav_date__gte=start_date_obj)
            except ValueError:
                pass
                
        if end_date:
            try:
                end_date_obj = datetime.strptime(end_date, '%Y-%m-%d').date()
                queryset = queryset.filter(nav_date__lte=end_date_obj)
            except ValueError:
                pass
        
        # 按日期排序
        queryset = queryset.order_by('-nav_date')
        
        # 序列化数据
        serializer = FundNavDetailSerializer(queryset, many=True)
        
        return Response({
            'status': 'success',
            'data': serializer.data,
            'count': queryset.count()
        })
        
    except Exception as e:
        logger.error(f"获取基金历史净值数据失败: {e}")
        return Response({
            'status': 'error',
            'message': f'获取数据失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def fund_nav_detail_latest(request):
    """
    获取基金净值详细数据的最新记录（按基金代码分组）
    支持分页查询
    """
    try:
        # 获取查询参数
        page = int(request.GET.get('page', 1))
        page_size = int(request.GET.get('page_size', 20))
        fund_code = request.GET.get('fund_code', '')
        
        # 使用原生SQL查询来解决MySQL不支持子查询LIMIT的问题
        from django.db import connection
        
        # 构建SQL查询
        sql = """
        SELECT t1.* FROM fund_nav_detail t1
        INNER JOIN (
            SELECT fund_code, MAX(nav_date) as max_date
            FROM fund_nav_detail
            {fund_code_filter}
            GROUP BY fund_code
        ) t2 ON t1.fund_code = t2.fund_code AND t1.nav_date = t2.max_date
        ORDER BY t1.fund_code
        """
        
        # 如果指定了基金代码，添加过滤条件
        if fund_code:
            fund_code_filter = f"WHERE fund_code LIKE '%{fund_code}%'"
        else:
            fund_code_filter = ""
        
        sql = sql.format(fund_code_filter=fund_code_filter)
        
        # 执行查询获取总数
        count_sql = f"""
        SELECT COUNT(*) as total FROM (
            {sql}
        ) as subquery
        """
        
        with connection.cursor() as cursor:
            cursor.execute(count_sql)
            total_count = cursor.fetchone()[0]
        
        # 添加分页
        start_index = (page - 1) * page_size
        paginated_sql = f"{sql} LIMIT {page_size} OFFSET {start_index}"
        
        # 执行分页查询
        queryset = FundNavDetail.objects.raw(paginated_sql)
        
        # 序列化数据
        serializer = FundNavDetailSerializer(list(queryset), many=True)
        
        # 计算分页信息
        total_pages = (total_count + page_size - 1) // page_size
        has_next = page < total_pages
        has_previous = page > 1
        
        return Response({
            'status': 'success',
            'data': serializer.data,
            'pagination': {
                'current_page': page,
                'page_size': page_size,
                'total_count': total_count,
                'total_pages': total_pages,
                'has_next': has_next,
                'has_previous': has_previous
            }
        })
        
    except Exception as e:
        logger.error(f"获取基金净值最新数据失败: {e}")
        return Response({
            'status': 'error',
            'message': f'获取数据失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def final_fund_scraper_latest(request):
    """
    获取基金净值数据（从final_fund_scraper表）
    支持分页查询
    返回字段：基金代码、基金名称、单位净值、累计净值、日收益率、净值日期
    """
    try:
        # 获取查询参数
        page = int(request.GET.get('page', 1))
        page_size = int(request.GET.get('page_size', 20))
        fund_code = request.GET.get('fund_code', '')
        
        # 构建查询条件
        queryset = FinalFundScraper.objects.all()
        
        # 如果指定了基金代码，添加过滤条件
        if fund_code:
            queryset = queryset.filter(fund_code__icontains=fund_code)
        
        # 按净值日期降序排列
        queryset = queryset.order_by('-nav_date', 'fund_code')
        
        # 获取总数
        total_count = queryset.count()
        
        # 分页
        start_index = (page - 1) * page_size
        end_index = start_index + page_size
        paginated_queryset = queryset[start_index:end_index]
        
        # 序列化数据
        serializer = FinalFundScraperSerializer(paginated_queryset, many=True)
        
        # 计算分页信息
        total_pages = (total_count + page_size - 1) // page_size
        has_next = page < total_pages
        has_previous = page > 1
        
        return Response({
            'status': 'success',
            'data': serializer.data,
            'pagination': {
                'current_page': page,
                'page_size': page_size,
                'total_count': total_count,
                'total_pages': total_pages,
                'has_next': has_next,
                'has_previous': has_previous
            }
        })
        
    except Exception as e:
        logger.error(f"获取基金净值数据失败: {e}")
        return Response({
            'status': 'error',
            'message': f'获取数据失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


# FundNavAPI实例缓存
_fund_nav_api_instance = None

def get_fund_nav_api():
    """获取FundNavAPI实例（单例模式）"""
    global _fund_nav_api_instance
    if _fund_nav_api_instance is None:
        try:
            # 获取数据库配置
            db_config = get_database_config()
            _fund_nav_api_instance = FundNavAPI(db_config)
        except Exception as e:
            logger.error(f"初始化FundNavAPI失败: {e}")
            raise
    return _fund_nav_api_instance


@api_view(['GET'])
@permission_classes([permissions.IsAuthenticated])
def fund_nav_history_api(request, fund_code):
    """
    使用FundNavAPI获取指定基金的历史净值数据
    支持时间范围过滤和多种查询参数
    """
    try:
        # 获取查询参数
        start_date = request.GET.get('start_date')
        end_date = request.GET.get('end_date')
        period = request.GET.get('period', 'all')  # all, 10y, 5y, 3y, 1y, ytd
        page_size = request.GET.get('page_size', '1000')  # 默认1000条记录
        page = request.GET.get('page', '1')  # 默认第1页
        
        # 获取FundNavAPI实例
        api = get_fund_nav_api()
        
        # 根据period参数设置时间范围
        if period != 'all' and not start_date:
            from datetime import datetime, timedelta
            end_date_obj = datetime.now().date()
            
            if period == '1y':
                start_date = (end_date_obj - timedelta(days=365)).strftime('%Y-%m-%d')
            elif period == '3y':
                start_date = (end_date_obj - timedelta(days=365*3)).strftime('%Y-%m-%d')
            elif period == '5y':
                start_date = (end_date_obj - timedelta(days=365*5)).strftime('%Y-%m-%d')
            elif period == '10y':
                start_date = (end_date_obj - timedelta(days=365*10)).strftime('%Y-%m-%d')
            elif period == 'ytd':
                start_date = f"{end_date_obj.year}-01-01"
        
        # 调用FundNavAPI查询历史数据
        result = api.get_fund_nav_history(
            fund_code=fund_code,
            start_date=start_date,
            end_date=end_date,
            page=int(page),
            page_size=int(page_size)
        )
        
        if result['success']:
            # 转换数据格式以匹配前端期望的格式
            nav_data = []
            for item in result['data']:
                nav_data.append({
                    'fund_code': item['fund_code'],
                    'nav_date': item['nav_date'],
                    'nav_value': float(item['unit_nav']) if item['unit_nav'] else None,
                    'accumulated_nav': float(item['accumulated_nav']) if item['accumulated_nav'] else None,
                    'daily_growth_rate': float(item['daily_growth_rate']) if item['daily_growth_rate'] else None,
                    'created_at': item.get('created_at'),
                    'updated_at': item.get('updated_at')
                })
            
            return Response({
                'status': 'success',
                'data': nav_data,
                'count': len(nav_data),
                'message': result.get('message', '查询成功')
            })
        else:
            return Response({
                'status': 'error',
                'message': result.get('message', '查询失败'),
                'data': []
            }, status=status.HTTP_400_BAD_REQUEST)
            
    except Exception as e:
        logger.error(f"使用FundNavAPI获取基金历史净值数据失败: {e}")
        return Response({
            'status': 'error',
            'message': f'获取数据失败: {str(e)}'
        }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
